//
// Ephi - simulation of magnetic fields and particles
// Copyright (C) 2007 Indrek Mandre <indrek(at)mare.ee>
// For more information please see http://www.mare.ee/indrek/ephi/
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include "statics.hpp"
#include "screen.hpp"
#include "dynamics.hpp"
#include "consts.hpp"

// send two electrons at angle towards each other, see what happens

// dist=0.000001
// q=1.602176487*10^-19
// k=8.988*10^9
// r1=dist * 2;
// r2=r1 / 10
// pe1=k * q * q /r1
// pe2=k * q * q /r2
// en=pe2 - pe1
// speed=en / (2 * q)
// speed =~ 0.0032400815096601eV

#define SPEED (0.0032400815096601)
#define TIME_TO_RUN 2e-10
#define DIST 0.000001

int main (int argc, char *argv[])
{
  Statics statics;
  ElectroDynamics dyn(statics);
  dyn.setDTM (1, 50); // default too inacurate, 10 is enough but not enough resolution to draw properly

  // firing at 45 degree angle so adjusting speed
  prec_t speed = ElectroDynamics::eV2ms(SPEED, ELECTRON_MASS);
  speed = ElectroDynamics::ms2eV (speed * PREC_SQRT2, ELECTRON_MASS);

  dyn.inject_electron (vect3d(-DIST, 0, 0), vect3d(1, 1, 0), speed);
  dyn.inject_electron (vect3d(DIST, 0, 0), vect3d(-1, 1, 0), speed);

  Screen screen(800, 800, 0.00001, 0.00001);
  screen.draw_axes(DIST/10);

#define PIXEL_INTERVAL 0.00000000000001
  prec_t cp = 0;

  while ( true )
    {
      if ( dyn.get_elapsed_time() >= cp )
        {
          screen.set_pixel (dyn.get_pos(0), Screen::RED);
          screen.set_pixel (dyn.get_pos(1), Screen::GREEN);
          cp += PIXEL_INTERVAL;
        }

      if ( dyn.get_elapsed_time() >= TIME_TO_RUN )
          break;
      dyn.step ();
    }
  
  prec_t y_diff = fabs(dyn.get_pos(0).y - dyn.get_pos(1).y);
  prec_t x_diff = dyn.get_pos(0).x + dyn.get_pos(1).x;

  screen.write ("test4.bmp");
  if ( dyn.get_pos(0).x > -DIST || dyn.get_pos(1).x < -DIST )
      printf ("ERROR=the red one did not move away to the left or green did not move away to the right\n");
  else if ( y_diff > dyn.get_pos(0).y / 1000 )
      printf ("ERROR=the particle's y does not match up\n");
  else if ( x_diff > fabs(dyn.get_pos(0).x / 1000) )
      printf ("ERROR=the particle's x does not match up\n");
  else
      printf ("OK=we didn't crash so that's good, check the test4.bmp to see if the red and green move away\n");

  printf ("YMARGIN=%g\n", prec2double(y_diff));
  printf ("XMARGIN=%g\n", prec2double(x_diff));
  char buf[128];
  printf ("LEFT=%s\n", dyn.get_pos(0).sprint(buf));
  printf ("RIGHT=%s\n", dyn.get_pos(1).sprint(buf));

  return 0;
}

